﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Collections;
using System.Xml.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace Dracham.Classes
{
    public partial class Character : MobileObject
    {
        public Boolean IsOnline { get; set; }
        public DateTime LastAttack { get; set; }

        public override void Initialize()
        {
            this.Position = new Position(this.PositionX, this.PositionY, this.ZoneId);
            base.Initialize();
        }

        public void PlayerKillObject(MobileObject mob)
        {
            Type t = mob.GetType();
        }

        public NetworkParameter[] CharacterDescription()
        {
            List<NetworkParameter> p = new List<NetworkParameter>();

            p.Add(new NetworkParameter(this.Name, 15));
            p.Add(new NetworkParameter(this.MaxHitpoints.ToString(), 4));
            p.Add(new NetworkParameter(this.CurrentHitpoints.ToString(), 4));
            p.Add(new NetworkParameter(this.ModelId, 10));
            p.Add(new NetworkParameter(this.ZoneId, 20));
            p.AddRange(this.Position.GetNetworkDescription());

            return p.ToArray();
        }

        public static void CharacterMovement(DrachamNetwork client)
        {
            Character.CharacterMovement(client, false);
        }

        public override void Expire()
        {
            base.Expire();
            this.Position.Zone.PlayerLeaveZone();

            Account acc = GameWorld.Accounts.SingleOrDefault(a => a.CurrentCharacter == this);
            if (acc != null)
            {
                if (!this.HasExpired) this.HasExpired = true;

                String msg = "DU ÄR FUCKING DöD, JÄVLA SOPA!";
                acc.Client.Invoke(MessageType.ChatMessage,
                    new NetworkParameter("System", 20),
                    new NetworkParameter(msg.Length.ToString(), 10),
                    new NetworkParameter(msg, msg.Length));
            }
        }

        public static void CharacterMovement(DrachamNetwork client, Boolean isChat)
        {
            String sessionKey = client.ReceiveString(36);

            Account acc = GameWorld.Accounts.Single(a => a.Client == client && a.SessionKey == sessionKey);

            if (acc != null)
            {
                String zoneId = client.ReceiveString(20);
                float x = float.Parse(client.ReceiveString(5));
                float y = float.Parse(client.ReceiveString(5));

                Position p = new Position(x, y, zoneId);

                if (acc.CurrentCharacter.Position.Distance(p) == 1)
                {
                    acc.CurrentCharacter.Move(p);
                }
                else
                {
                    List<NetworkParameter> netParams = new List<NetworkParameter>();
                    netParams.Add(new NetworkParameter(acc.CurrentCharacter.Position.ZoneId, 20));
                    netParams.AddRange(acc.CurrentCharacter.Position.GetNetworkDescription());
                    client.Invoke(MessageType.CharacterMovement, netParams.ToArray());
                }
            }
        }

        public void Move(Position to)
        {
            Position oldPos = (Position)this.Position.Clone();
            this.Position = to;
            this.PositionX = (int)to.X;
            this.PositionY = (int)to.Y;

            foreach (Account account in this.Position.Zone.GetCharactersInZone().Where(a => a != this.Account))
            {
                List<NetworkParameter> netParams = new List<NetworkParameter>();
                netParams.Add(new NetworkParameter(this.Id.ToString(), 36));
                netParams.Add(new NetworkParameter(this.ModelId.ToString(), 20));
                netParams.Add(new NetworkParameter(this.Position.ZoneId, 20));
                netParams.AddRange(oldPos.GetNetworkDescription());
                netParams.AddRange(this.Position.GetNetworkDescription());
                account.Client.Invoke(MessageType.MobMovement, netParams.ToArray());
            }

            Tile t = this.Position.Zone.FindTile(this.Position);
            if (t != null)
            {
                t.Step(this);
            }

        }
    }
}
